﻿// ## 2023/11/06 # 铃 # 创建逻辑 用于进攻时候AI的设施修建##


namespace 进攻型建筑设施修建优化
{
    //=======================================================================================


    bool 调试模式 = false;

//=======================================================================================

    class pos_score
    {
        pk::point pos;
        int score1;
        int score2;

    };
    pos_score pos_score_;


        //---------------------------------------------------------------------------

    array<pos_score> p_score_arr;

    //---------------------------------------------------------------------------

    unit_order_info func_build(pk::unit @unit)
    {
        unit_order_info info;

        if (!pk::is_alive(unit))
            return info;

        if (unit.gold < 500 or unit.troops < 3000)
            return info;

        if (unit.order == 部队任务_撤退)
            return info;

        if (unit.order == 部队任务_设置)
            return info;

        if (unit.order == 部队任务_修复)
            return info;

        if (unit.weapon > 兵器_战马 and unit.weapon < 兵器_走舸)
            return info;

       // pk::info(pk::format("3.修建建筑 {}", pk::decode(pk::get_name(unit))));

        pos_score pos_info;
        p_score_arr.resize(0);

        pk::array<pk::point> arr_range = pk::get_movable_pos(unit);
        if (arr_range.length == 0)
            return info; //暂时什么都不做
        int count_siege = 0;

        if (arr_range.length > 0)
        {
            for (int i = 0; i < int(arr_range.length); i++)
            {

                pk::hex @hex = pk::get_hex(arr_range[i]);

                if (!pk::is_valid_pos(arr_range[i]))
                    continue;

                if (hex.has_building)
                    continue;

                if (hex.has_unit)
                    continue;

                if (!hex.can_military)
                    continue;


                if (hex.terrain != 地形_官道 and hex.terrain != 地形_土 and hex.terrain != 地形_草地 and hex.terrain != 地形_砂地)
                    continue;


                int count_enemy5 = 0;
                int count_ally5 = 0;

                int count_enemy3 = 0;
                int count_ally3 = 0;
                pos_info.score1 = 0;
                pos_info.score2 = 0;

                array<pk::point> search_unit_range = pk::range(arr_range[i], 1, 5);
                count_siege = 0;
                for (int arr_index = 0; arr_index < int(search_unit_range.length); arr_index++)
                {
                    pk::hex @hex0 = pk::get_hex(search_unit_range[arr_index]);

                    if (hex0.has_unit)
                    {
                        auto search_unit = pk::get_unit(search_unit_range[arr_index]);
                        if (search_unit.get_id() != unit.get_id())
                        {
                            int distance = pk::get_distance(arr_range[i], search_unit.pos);
                             //附近有重兵器的时候不造

                            //pk::trace(pk::format("{},找到部队兵器为{},分数1:{},距离为{}", pk::decode(pk::get_name(unit)), search_unit.weapon, pos_info.score1, distance));

                            if (pk::is_enemy(unit, search_unit) and search_unit.weapon == 兵器_投石)
                                count_siege += 1;

                            if (pk::is_enemy(unit, search_unit) and (search_unit.weapon == 兵器_木兽 or search_unit.weapon == 兵器_冲车))
                                count_siege += 2;

                            if (pk::is_enemy(unit, search_unit))count_enemy5++;
                            if (!pk::is_enemy(unit, search_unit))count_ally5++;
                            if (pk::is_enemy(unit, search_unit) and distance <= 3)count_enemy3++;
                            if (!pk::is_enemy(unit, search_unit) and distance <= 3)count_ally3++;

                            //score1为敌军越多分越高,用于建设箭塔投石等进攻建筑,从1分到5分
                            if (pk::is_enemy(unit, search_unit))
                            {
                                pos_info.score1 += pk::min(3, 6 - distance) * 2;  //1格未必比2格和3格好,因此设定上限3
                            }

                            //pk::trace(pk::format("{},找到{},分数1:{},距离为{}", pk::decode(pk::get_name(unit)), pk::decode(pk::get_name(search_unit)), pos_info.score1, distance));

                            //score2为友军越多分越高,用于阵和军乐台等防御建筑,从1分到5分
                            if (!pk::is_enemy(unit, search_unit))
                            {
                                pos_info.score2 += pk::min(5, 6 - pk::get_distance(search_unit_range[arr_index], search_unit.pos)); //1格肯定更好,因此上限为5
                            }
                        }
                    }

                    //pk::trace(pk::format("{},搜索可用坐标{},{},count_siege{}", pk::decode(pk::get_name(unit)), arr_range[i].x, arr_range[i].y, count_siege));



                    if (hex0.has_building)
                    {
                        auto search_building = pk::get_building(search_unit_range[arr_index]);
                        if (pk::is_enemy(unit, search_building))count_enemy5++;
                        if (!pk::is_enemy(unit, search_building))count_ally5++;
                        if (pk::is_enemy(unit, search_building) and search_building.get_id() < 城市_末)count_enemy5++;
                        if (pk::is_enemy(unit, search_building) and search_building.get_id() < 据点_末)count_enemy5++;

                        //score1为敌军越多分越高
                        if (pk::is_enemy(unit, search_building))
                        {
                            pos_info.score1 += pk::min(2, 5 - pk::get_distance(unit.pos, search_building.pos));  //1格未必比2格和3格好,因此设定上限3
                        }

                        if (pk::is_enemy(unit, search_building) and search_building.get_id() < 城市_末)
                        {
                            pos_info.score1 += pk::min(2, 5 - pk::get_distance(unit.pos, search_building.pos));  //1格未必比2格和3格好,因此设定上限3
                        }

                        if (pk::is_enemy(unit, search_building) and search_building.get_id() < 据点_末)
                        {
                            pos_info.score1 += pk::min(3, 6 - pk::get_distance(unit.pos, search_building.pos));  //1格未必比2格和3格好,因此设定上限3
                        }

                    }

                }
                if (count_siege >= 2) continue;
                //pk::trace(pk::format("{},搜索可用坐标{},{},打分{},{},count_enemy5:{},count_ally5:{},count_enemy3:{},count_ally3:{}", pk::decode(pk::get_name(unit)), arr_range[i].x, arr_range[i].y, pos_info.score1, pos_info.score2, count_enemy5, count_ally5, count_enemy3, count_ally3));
                //如果附近敌军或者友军太少,就不用考虑(非战场)
                if (count_enemy5 <= 2 or count_ally5 <= 2) continue;
                if (count_enemy3 == 0 or count_ally3 == 0) continue;
                if (pos_info.score1 < 15 or pos_info.score2 < 5) continue;


                pos_info.pos = arr_range[i];

                p_score_arr.insertLast(pos_info);
            }
        }

        if (p_score_arr.length == 0) return info; //暂时什么都不做

        //先考虑修阵的情况score1+score2
        p_score_arr.sort(function(a, b) {
            return a.score1 + a.score2 > b.score1 + b.score2;
        });

        if (pos_info.score1 >= pos_info.score2 / 2)
        {
            if (pk::rand(10) > 5)
            {
                info.id = unit.get_id();
                info.order = 部队任务_设置;
                info.pos = pos_info.pos;
                info.score = 1000;
                info.target = 工事_箭塔;
            }
            else
            {
                info.id = unit.get_id();
                info.order = 部队任务_设置;
                info.pos = pos_info.pos;
                info.score = 1000;
                info.target = 工事_阵;
            }
        }
        if (pos_info.score1 < pos_info.score2 / 2)
        {
            if (pos_info.score1 < pos_info.score2 / 8 and pk::rand(10) >5)
            {
                info.id = unit.get_id();
                info.order = 部队任务_设置;
                info.pos = pos_info.pos;
                info.score = 1000;
                info.target = 工事_军乐台;
            }
            else if (pk::rand(10) > 5)
            {
                info.id = unit.get_id();
                info.order = 部队任务_设置;
                info.pos = pos_info.pos;
                info.score = 1000;
                info.target = 工事_阵;
            }
            else
            {
                info.id = unit.get_id();
                info.order = 部队任务_设置;
                info.pos = pos_info.pos;
                info.score = 1000;
                info.target = 工事_箭塔;
            }
        }
        return info;
//pk::trace(pk::format("{}修建工事:目标坐标为{},", pk::decode(pk::get_name(unit)), unit.target));
    }


    unit_order_info func_repair(pk::unit @unit)
    {
        unit_order_info info;
        if (!pk::is_alive(unit))
            return info;

        if (unit.order == 部队任务_设置)
            return info;

        if (unit.order == 部队任务_修复)
            return info;

        if (unit.order == 部队任务_撤退)
            return info;


       // pk::trace(pk::format("2{}修补阵:目标坐标为{},{},", pk::decode(pk::get_name(unit)), unit.pos.x, unit.pos.y));

        if (unit.weapon > 兵器_战马 and unit.weapon < 兵器_走舸)
            return info;

        //pk::trace(pk::format("3{}修补阵:目标坐标为{},{},", pk::decode(pk::get_name(unit)), unit.pos.x, unit.pos.y));

        pk::array<pk::point> arr_range = pk::get_movable_pos(unit);
        if (arr_range.length == 0)
            return info; //暂时什么都不做

            //pk::trace(pk::format("4{}修补阵:目标坐标为{},{},", pk::decode(pk::get_name(unit)), unit.pos.x, unit.pos.y));

        if (arr_range.length > 0)
        {
            for (int i = 0; i < int(arr_range.length); i++)
            {
                if (!pk::is_valid_pos(arr_range[i]))
                    continue;

                pk::array<pk::point> arr_t = pk::range(arr_range[i], 1, 1); // 周围坐标

                for (int t = 0; t < int(arr_t.length); t++)
                {

                    pk::hex @hex = pk::get_hex(arr_t[t]);

                    //pk::trace(pk::format("5{}修补阵:目标坐标为{},{},是否有建筑{},", pk::decode(pk::get_name(unit)), arr_t[t].x, arr_t[t].y, hex.has_building));

                    if (hex.has_building)
                    {
                        pk::building @building = pk::get_building(arr_t[t]);

                        //pk::trace(pk::format("{}修补阵前置:目标坐标为{},{},", pk::decode(pk::get_name(unit)), arr_t[t].x, arr_t[t].y));

                        if (building.get_force_id() == unit.get_force_id() and building.facility <= 设施_石兵八阵 and (ch::enemy_troop_base_near_distance(building, 3) > 0 or !building.completed) and (int(building.hp) < int(pk::get_max_hp(building) * 0.9) or !building.completed))
                        //if (building.get_force_id() == unit.get_force_id()  and int(building.hp) < int(pk::get_max_hp(building) * 0.9))
                        {
                            array<pk::point> search_unit_range = pk::range(building.pos, 1, 5);
                            int count_siege = 0;
                            for (int arr_index = 0; arr_index < int(search_unit_range.length); arr_index++)
                            {
                                pk::hex @hex0 = pk::get_hex(search_unit_range[arr_index]);
                                if (hex0.has_unit)
                                {
                                    auto search_unit = pk::get_unit(search_unit_range[arr_index]);
                                     //附近有重兵器的时候不造

                                    if (pk::is_enemy(unit, search_unit) and search_unit.weapon == 兵器_投石)
                                        count_siege += 1;

                                    if (pk::is_enemy(unit, search_unit) and (search_unit.weapon == 兵器_木兽 or search_unit.weapon == 兵器_冲车))
                                        count_siege += 2;
                                }
                            }
                            if (count_siege < 2)
                            {
                                info.id = unit.get_id();
                                info.order = 部队任务_修复;
                                info.pos = arr_t[t];
                                info.score = 1000;
                             //pk::trace(pk::format("{},{}修补前:目标坐标为{},{},建筑HP{},", pk::decode(pk::get_name(unit)),unit.get_id(), unit.target.pos.x, unit.target.pos.y, building.hp));

                            }

                        }
                    }
                }
            }
        }
        return info;
    }




    //---------------------------------------------------------------------------------------

    string get_order_info(int order)
    {
        string name;
        switch (order)
        {
            case 0:
                name = "部队任务_待命";
                break;
            case 1:
                name = "部队任务_移动";
                break;
            case 2:
                name = "部队任务_设置";
                break;
            case 3:
                name = "部队任务_攻击";
                break;
            case 4:
                name = "部队任务_撤退";
                break;
            case 5:
                name = "部队任务_拦截";
                break;
            case 6:
                name = "部队任务_护卫";
                break;
            case 7:
                name = "部队任务_攻城";
                break;
            case 8:
                name = "部队任务_修复";
                break;
            case 9:
                name = "部队任务_征服";
                break;
            case 10:
                name = "部队任务_补给";
                break;
            case 11:
                name = "部队任务_歼灭";
                break;
            case 12:
                name = "部队任务_追随";
                break;
            case 13:
                name = "部队任务_末";
                break;
            default:
                name = "部队任务_无";
                break;
        }

        return name;
    }

}
